package mop.controller;
import java.util.LinkedList;
import java.util.List;

import mop.exception.IllegalIdException;
import mop.model.World;
import mop.model.project.ProjectInterface;
import mop.model.resource.ResourceInterface;
import mop.model.task.Task;
import mop.model.task.TaskInterface;
import mop.model.user.User;
import mop.model.user.UserInterface;

/**
 * UseCaseController
 * 
 * Defines a number of useful methods for the different Controllers
 * that allow for easy switching between interfaces and Strings
 * and vice versa
 * 
 * @author MOP Team 7
 */
public abstract class UseCaseController
{

	/**
	 * Constructor
	 * @param world	
	 *		  The world object
	 * @post World reference is set
	 * 		|this.world == world
	 */
	UseCaseController(World world)
	{
		this.world = world;
	}
	
	/**
	 * Return a list with all possible projects
	 * @return A list of interfaces to projects
	 */
	protected List<ProjectInterface> getAllProjects()
	{
		List<ProjectInterface> list = new LinkedList<ProjectInterface>();
		list.addAll(getWorld().getProjectDataBase().fetchAll());
		return list;
	}
	
	/**
	 * Return a list with all possible resources
	 * @return A list of interfaces to resources
	 */
	protected List<ResourceInterface> getAllResources()
	{
		List<ResourceInterface> list = new LinkedList<ResourceInterface>();
		list.addAll(getWorld().getResourceDataBase().fetchAll());
		return list;
	}
	
	/**
	 * Return a list with all existing tasks
	 * @return A list of interfaces to all tasks in system
	 */
	protected List<TaskInterface> getAllTasks()
	{
		List<TaskInterface> list = new LinkedList<TaskInterface>();
		list.addAll(getWorld().getAllTasks());
		return list;
	}
	
	/**
	 * Returns a list of tasks belonging to the current user.
	 * @return	A (linked) list of tasks belonging to the current user.
	 */
	protected List<TaskInterface> getUserTasks()
	{
		LinkedList<TaskInterface> userTasks = new LinkedList<TaskInterface>();
		User currentUser = getWorld().getCurrentUser(); 
		userTasks.addAll(currentUser.getTasks());
		return userTasks;
	}
	
	/**
	 * Return a list with all possible users
	 * @return A list of interfaces to users
	 */
	protected List<UserInterface> getAllUsers()
	{
		List<UserInterface> list = new LinkedList<UserInterface>();
		list.addAll(getWorld().getUserDataBase().fetchAll());
		return list;
	}
	
	/**
	 * Parse String list to Tasks
	 * 
	 * @param ids	
	 * 		  The id's for the tasks
	 * @throws IllegalIdException 
	 * 		   If one of the passed id's doesn't exist
	 * 			|@see getTask(String)
	 * @return A list of tasks
	 */
	protected List<Task> getTaskList(List<String> ids) throws IllegalIdException
	{
		List<Task> tasks = new LinkedList<Task>();
		for(String id : ids)
		{
			tasks.add(getTask(id));
		}
		return tasks;
	}
	
	/**
	 * Find a task that matches a certain id
	 * 
	 * @param 	task	
	 * 			The task to be converted
	 * @throws 	IllegalIdException
	 * 			If the given id doesn't exist
	 * 			 |getWorld().findTask(id)
	 * @return 	The matching task
	 */
	protected Task getTask(String id) 
		throws IllegalIdException
	{
		return getWorld().findTask(id);
	}
	
	/***************************************************************************
	 * 								World
	 ***************************************************************************/
	
	/**
	 * Inspector for World
	 * @return this.world
	 */
	protected World getWorld()
	{
		return this.world;
	}
	
	/**
	 * A pointer to the system
	 */
	private World world;
	
	
	/***************************************************************************
	 * 								Visit
	 ***************************************************************************/
	
	public abstract void visit(ControllerVisitor v);
}